package com.ume.supplier.cn.httputil.http

import com.google.gson.internal.`$Gson$Types`
import com.ume.supplier.cn.httputil.http.BaseModel
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

/**
 * Created by joe on 2018/7/2
 */
abstract class HttpCallback<T> {
    private var mType: Type? = null

    init {
        mType = getSuperclassTypeParameter(javaClass)
    }

    companion object {
        private val TYPE_NAME_PREFIX = "class "
        @Throws(ClassNotFoundException::class)
        fun getClass(type: Type): Class<*>? {
            val className = getClassName(type)
            return if (className == null || className.isEmpty()) {
                null
            } else Class.forName(className)
        }

        fun getClassName(type: Type?): String {
            if (type == null) {
                return ""
            }
            var className = type.toString()
            if (className.startsWith(TYPE_NAME_PREFIX)) {
                className = className.substring(TYPE_NAME_PREFIX.length)
            }
            return className
        }

    }

    abstract fun onSuccess(response: T)

    @Deprecated(message = "No longer use", level = DeprecationLevel.WARNING)
    open fun onRequestError(message: String,code:Int) {

    }

    abstract fun onFailure(message: String?, err: Throwable)
    open fun onBefore(){

    }

    internal fun getSuperclassTypeParameter(subclass: Class<*>?): Type? {
        val superclass = subclass!!.genericSuperclass
        if (superclass is Class<*>) {
            throw RuntimeException("Missing type parameter.")
        }
        val parameterized = superclass as ParameterizedType
        return `$Gson$Types`.canonicalize(parameterized.actualTypeArguments[0])
    }

    fun getT(): T? {
        try {

//            val genType = javaClass.genericSuperclass as ParameterizedType
//            val params = genType.actualTypeArguments
//
//            // 第二层泛型的类型, 也就是这里传入的 T 的具体类型 例如 BaseResponse<LoginBean>
//            val type = params[0] as? ParameterizedType ?: throw IllegalStateException("没有填写泛型参数")
//
//            // 获取第二层数据的真实类型 BaseResponse
//            val rawType = type.rawType
//
//            // 获取第二层数据泛型的真实类型,也就是 BaseResponse 中的 T 为 LoginBean
//            val typeArgument = type.actualTypeArguments[0]

            if (mType is ParameterizedType) {
                val pt = mType!! as ParameterizedType
                val rawTypeStr = pt.rawType.toString()
                val baseModelClassName = BaseModel::class.java.name
                if (rawTypeStr.contains(baseModelClassName)) {
                    if (pt.actualTypeArguments.isNotEmpty()) {
                        val argsTypeStr = pt.actualTypeArguments[0].toString()
                        if (argsTypeStr.contains(String::class.java.name)) {
                            return BaseModel<String>() as T
                        }

                        if (argsTypeStr.contains(Any::class.java.name)) {
                            return BaseModel<String>() as T
                        }
                    }
                }
            }

            val o = HttpCallback.getClass(mType!!)?.newInstance()
            if (o != null) {
                return o as T
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return null
    }

}